package com.iakuil.app.api.controller;


import cn.dev33.satoken.secure.BCrypt;
import com.iakuil.app.common.core.BaseController;
import com.iakuil.app.common.core.annotation.Log;
import com.iakuil.app.common.core.domain.Result;
import com.iakuil.app.common.core.enums.OpType;
import com.iakuil.app.common.core.jsr303.constraints.Ids;
import com.iakuil.app.common.core.util.StringUtils;
import com.iakuil.app.domain.dto.UserDto;
import com.iakuil.app.domain.dto.cmd.UserAdd;
import com.iakuil.app.domain.dto.cmd.UserEdit;
import com.iakuil.app.domain.dto.query.UserQuery;
import com.iakuil.app.domain.dto.vo.UserInfoVo;
import com.iakuil.app.domain.entity.User;
import com.iakuil.app.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 用户 接口
 *
 * @author Kai
 * @date 2024-01-26
 */
@Tag(name = "用户管理", description = "用户管理接口（管理员）")
@RestController
@RequestMapping("/api/v1/user")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UserController extends BaseController {
    private final UserService userService;

    @Operation(summary = "用户详情", description = "根据ID查询用户。")
    @Parameter(name = "id", description = "ID", required = true, in = ParameterIn.QUERY)
    @GetMapping
    public Result<UserInfoVo> doQuery(@RequestParam Long id) {
        User entity = userService.getById(id);
        return success(entity, UserInfoVo.class);
    }

    @Operation(summary = "用户列表", description = "分页查询用户数据。")
    @PostMapping(value = "/list")
    public Result<UserDto> doPaging(@RequestBody UserQuery param) {
        User entity = convert(param, User.class);
        startPage();
        return pageInfo(userService.list(entity, param.getFields()))
            .map(e -> convert(e, UserDto.class));
    }

    @Operation(summary = "用户新增", description = "新增用户。")
    @Log(title = "用户", type = OpType.INSERT)
    @PostMapping(value = "/create")
    public Result<?> doCreate(@Validated @RequestBody UserAdd param) {
        User entity = convert(param, User.class);
        entity.setPassword(BCrypt.hashpw(param.getPassword()));
        userService.checkUnique(entity);
        return success(userService::save, entity);
    }

    @Operation(summary = "用户修改", description = "修改用户信息。")
    @Log(title = "用户", type = OpType.UPDATE)
    @PostMapping(value = "/edit")
    public Result<Void> doEdit(@Validated @RequestBody UserEdit param) {
        User entity = convert(param, User.class);
        String plainPw = param.getPassword();
        if (StringUtils.isNotBlank(plainPw)) {
            entity.setPassword(BCrypt.hashpw(plainPw));
        }
        userService.checkUnique(entity);
        return success(userService.modify(entity));
    }

    @Operation(summary = "用户删除", description = "批量删除用户。")
    @Parameter(name = "ids", description = "ID列表，逗号分隔，无需方括号", required = true, in = ParameterIn.QUERY)
    @Log(title = "用户", type = OpType.DELETE)
    @PostMapping(value = "/remove")
    public Result<Void> doRemove(@RequestParam @Ids Long[] ids) {
        userService.removeByIds(ids);
        return success();
    }
}
